package com.example.demo.test;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class demo7 {

    private static final BlockingQueue<String> blockQueue = new ArrayBlockingQueue<>(10);
    private boolean isConsumer1 = true;

    public synchronized void consumerLock(String consumerName) throws InterruptedException {
        while (true){
            //  如果线程1 进来，但是当前不是线程1执行的时候（!isConsumer1 = true）== 线程2执行时,线程1等待！！！！释放锁。
            //  如果线程1 进来，但是当前是线程1执行的时候。就不会进入等待
            // 重要的是这个条件进入的  等待，不是  执行。 我们的思维会默认进入  执行  的思路。所以就觉的不对劲
            // 如果我们理解成：线程1进来，先让线程2等待，再执行 线程1.
            if (consumerName.equals("consumer1")){
                if (!isConsumer1){
                    wait();
                    continue;
                }
            }else{
                if (isConsumer1){
                    wait();
                    continue;
                }
            }

            System.out.println(consumerName+":"+blockQueue.take());
            isConsumer1 = ! isConsumer1;
            notifyAll();
        }
    }


    public static void main(String[] args) throws Exception{
        demo7 demo7 = new demo7();
        Thread producer = new Thread(()->{
            for (int i = 0; i < 10; i++) {
                blockQueue.add(i+"");
            }
        });

        Thread consumer1 =new Thread(()->{
            for (int i = 0; i < 5; i++) {
                try {
                    demo7.consumerLock("consumer1");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

         Thread consumer2 =new Thread(()->{
             for (int i = 0; i < 5; i++) {
                 try {
                     demo7.consumerLock("consumer2");
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }             }
        });

        producer.start();
        consumer1.start();
        consumer2.start();
        try {
            // 主线程等待当前子线程全部执行完毕 , 如果不加这个，System.out.println("123"); 可能会先执行。
            // 如果子线程中有无线循环，那么，这个主线程也不会执行了。
            producer.join();
            consumer1.join();
            consumer2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
        System.out.println("123");
    }
}
